{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "feature_sets.ipynb",
      "version": "0.3.2",
      "provenance": [],
      "collapsed_sections": [
        "IGINhMIJ5Wyt",
        "pZa8miwu6_tQ",
        "copyright-notice"
      ]
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "copyright-notice",
        "colab_type": "text"
      },
      "source": [
        "#### Copyright 2017 Google LLC."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "both",
        "id": "copyright-notice2",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zbIgBK-oXHO7",
        "colab_type": "text"
      },
      "source": [
        " # 特征集"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "bL04rAQwH3pH",
        "colab_type": "text"
      },
      "source": [
        " **学习目标**：创建一个包含极少特征但效果与更复杂的特征集一样出色的集合"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "F8Hci6tAH3pH",
        "colab_type": "text"
      },
      "source": [
        " 到目前为止，我们已经将所有特征添加到了模型中。具有较少特征的模型会使用较少的资源，并且更易于维护。我们来看看能否构建这样一种模型：包含极少的住房特征，但效果与使用数据集中所有特征的模型一样出色。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "F5ZjVwK_qOyR",
        "colab_type": "text"
      },
      "source": [
        " ## 设置\n",
        "\n",
        "和之前一样，我们先加载并准备加利福尼亚州住房数据。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "SrOYRILAH3pJ",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "from __future__ import print_function\n",
        "\n",
        "import math\n",
        "\n",
        "from IPython import display\n",
        "from matplotlib import cm\n",
        "from matplotlib import gridspec\n",
        "from matplotlib import pyplot as plt\n",
        "import numpy as np\n",
        "import pandas as pd\n",
        "from sklearn import metrics\n",
        "import tensorflow as tf\n",
        "from tensorflow.python.data import Dataset\n",
        "\n",
        "tf.logging.set_verbosity(tf.logging.ERROR)\n",
        "pd.options.display.max_rows = 10\n",
        "pd.options.display.float_format = '{:.1f}'.format\n",
        "\n",
        "california_housing_dataframe = pd.read_csv(\"https://download.mlcc.google.cn/mledu-datasets/california_housing_train.csv\", sep=\",\")\n",
        "\n",
        "california_housing_dataframe = california_housing_dataframe.reindex(\n",
        "    np.random.permutation(california_housing_dataframe.index))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "dGnXo7flH3pM",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def preprocess_features(california_housing_dataframe):\n",
        "  \"\"\"Prepares input features from California housing data set.\n",
        "\n",
        "  Args:\n",
        "    california_housing_dataframe: A Pandas DataFrame expected to contain data\n",
        "      from the California housing data set.\n",
        "  Returns:\n",
        "    A DataFrame that contains the features to be used for the model, including\n",
        "    synthetic features.\n",
        "  \"\"\"\n",
        "  selected_features = california_housing_dataframe[\n",
        "    [\"latitude\",\n",
        "     \"longitude\",\n",
        "     \"housing_median_age\",\n",
        "     \"total_rooms\",\n",
        "     \"total_bedrooms\",\n",
        "     \"population\",\n",
        "     \"households\",\n",
        "     \"median_income\"]]\n",
        "  processed_features = selected_features.copy()\n",
        "  # Create a synthetic feature.\n",
        "  processed_features[\"rooms_per_person\"] = (\n",
        "    california_housing_dataframe[\"total_rooms\"] /\n",
        "    california_housing_dataframe[\"population\"])\n",
        "  return processed_features\n",
        "\n",
        "def preprocess_targets(california_housing_dataframe):\n",
        "  \"\"\"Prepares target features (i.e., labels) from California housing data set.\n",
        "\n",
        "  Args:\n",
        "    california_housing_dataframe: A Pandas DataFrame expected to contain data\n",
        "      from the California housing data set.\n",
        "  Returns:\n",
        "    A DataFrame that contains the target feature.\n",
        "  \"\"\"\n",
        "  output_targets = pd.DataFrame()\n",
        "  # Scale the target to be in units of thousands of dollars.\n",
        "  output_targets[\"median_house_value\"] = (\n",
        "    california_housing_dataframe[\"median_house_value\"] / 1000.0)\n",
        "  return output_targets"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jLXC8y4AqsIy",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1209
        },
        "outputId": "185a8f96-c153-4430-d972-166f8a228d56"
      },
      "source": [
        "# Choose the first 12000 (out of 17000) examples for training.\n",
        "training_examples = preprocess_features(california_housing_dataframe.head(12000))\n",
        "training_targets = preprocess_targets(california_housing_dataframe.head(12000))\n",
        "\n",
        "# Choose the last 5000 (out of 17000) examples for validation.\n",
        "validation_examples = preprocess_features(california_housing_dataframe.tail(5000))\n",
        "validation_targets = preprocess_targets(california_housing_dataframe.tail(5000))\n",
        "\n",
        "# Double-check that we've done the right thing.\n",
        "print(\"Training examples summary:\")\n",
        "display.display(training_examples.describe())\n",
        "print(\"Validation examples summary:\")\n",
        "display.display(validation_examples.describe())\n",
        "\n",
        "print(\"Training targets summary:\")\n",
        "display.display(training_targets.describe())\n",
        "print(\"Validation targets summary:\")\n",
        "display.display(validation_targets.describe())"
      ],
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Training examples summary:\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>latitude</th>\n",
              "      <th>longitude</th>\n",
              "      <th>housing_median_age</th>\n",
              "      <th>total_rooms</th>\n",
              "      <th>total_bedrooms</th>\n",
              "      <th>population</th>\n",
              "      <th>households</th>\n",
              "      <th>median_income</th>\n",
              "      <th>rooms_per_person</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>count</th>\n",
              "      <td>12000.0</td>\n",
              "      <td>12000.0</td>\n",
              "      <td>12000.0</td>\n",
              "      <td>12000.0</td>\n",
              "      <td>12000.0</td>\n",
              "      <td>12000.0</td>\n",
              "      <td>12000.0</td>\n",
              "      <td>12000.0</td>\n",
              "      <td>12000.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>mean</th>\n",
              "      <td>35.6</td>\n",
              "      <td>-119.6</td>\n",
              "      <td>28.6</td>\n",
              "      <td>2641.8</td>\n",
              "      <td>540.3</td>\n",
              "      <td>1430.3</td>\n",
              "      <td>502.2</td>\n",
              "      <td>3.9</td>\n",
              "      <td>2.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>std</th>\n",
              "      <td>2.1</td>\n",
              "      <td>2.0</td>\n",
              "      <td>12.6</td>\n",
              "      <td>2175.2</td>\n",
              "      <td>424.3</td>\n",
              "      <td>1163.3</td>\n",
              "      <td>387.7</td>\n",
              "      <td>1.9</td>\n",
              "      <td>1.3</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>min</th>\n",
              "      <td>32.5</td>\n",
              "      <td>-124.3</td>\n",
              "      <td>1.0</td>\n",
              "      <td>8.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>3.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>0.5</td>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>25%</th>\n",
              "      <td>33.9</td>\n",
              "      <td>-121.8</td>\n",
              "      <td>18.0</td>\n",
              "      <td>1467.0</td>\n",
              "      <td>296.0</td>\n",
              "      <td>790.0</td>\n",
              "      <td>282.0</td>\n",
              "      <td>2.6</td>\n",
              "      <td>1.5</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>50%</th>\n",
              "      <td>34.2</td>\n",
              "      <td>-118.5</td>\n",
              "      <td>29.0</td>\n",
              "      <td>2131.0</td>\n",
              "      <td>435.0</td>\n",
              "      <td>1165.0</td>\n",
              "      <td>410.0</td>\n",
              "      <td>3.5</td>\n",
              "      <td>1.9</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>75%</th>\n",
              "      <td>37.7</td>\n",
              "      <td>-118.0</td>\n",
              "      <td>37.0</td>\n",
              "      <td>3135.2</td>\n",
              "      <td>646.0</td>\n",
              "      <td>1715.2</td>\n",
              "      <td>604.0</td>\n",
              "      <td>4.8</td>\n",
              "      <td>2.3</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>max</th>\n",
              "      <td>42.0</td>\n",
              "      <td>-114.5</td>\n",
              "      <td>52.0</td>\n",
              "      <td>37937.0</td>\n",
              "      <td>6445.0</td>\n",
              "      <td>35682.0</td>\n",
              "      <td>6082.0</td>\n",
              "      <td>15.0</td>\n",
              "      <td>55.2</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "       latitude  longitude  ...  median_income  rooms_per_person\n",
              "count   12000.0    12000.0  ...        12000.0           12000.0\n",
              "mean       35.6     -119.6  ...            3.9               2.0\n",
              "std         2.1        2.0  ...            1.9               1.3\n",
              "min        32.5     -124.3  ...            0.5               0.0\n",
              "25%        33.9     -121.8  ...            2.6               1.5\n",
              "50%        34.2     -118.5  ...            3.5               1.9\n",
              "75%        37.7     -118.0  ...            4.8               2.3\n",
              "max        42.0     -114.5  ...           15.0              55.2\n",
              "\n",
              "[8 rows x 9 columns]"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "Validation examples summary:\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>latitude</th>\n",
              "      <th>longitude</th>\n",
              "      <th>housing_median_age</th>\n",
              "      <th>total_rooms</th>\n",
              "      <th>total_bedrooms</th>\n",
              "      <th>population</th>\n",
              "      <th>households</th>\n",
              "      <th>median_income</th>\n",
              "      <th>rooms_per_person</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>count</th>\n",
              "      <td>5000.0</td>\n",
              "      <td>5000.0</td>\n",
              "      <td>5000.0</td>\n",
              "      <td>5000.0</td>\n",
              "      <td>5000.0</td>\n",
              "      <td>5000.0</td>\n",
              "      <td>5000.0</td>\n",
              "      <td>5000.0</td>\n",
              "      <td>5000.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>mean</th>\n",
              "      <td>35.6</td>\n",
              "      <td>-119.6</td>\n",
              "      <td>28.5</td>\n",
              "      <td>2648.2</td>\n",
              "      <td>537.2</td>\n",
              "      <td>1427.7</td>\n",
              "      <td>498.8</td>\n",
              "      <td>3.9</td>\n",
              "      <td>2.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>std</th>\n",
              "      <td>2.2</td>\n",
              "      <td>2.0</td>\n",
              "      <td>12.5</td>\n",
              "      <td>2191.5</td>\n",
              "      <td>414.8</td>\n",
              "      <td>1110.1</td>\n",
              "      <td>376.8</td>\n",
              "      <td>1.9</td>\n",
              "      <td>0.9</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>min</th>\n",
              "      <td>32.5</td>\n",
              "      <td>-124.2</td>\n",
              "      <td>2.0</td>\n",
              "      <td>2.0</td>\n",
              "      <td>2.0</td>\n",
              "      <td>6.0</td>\n",
              "      <td>2.0</td>\n",
              "      <td>0.5</td>\n",
              "      <td>0.1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>25%</th>\n",
              "      <td>33.9</td>\n",
              "      <td>-121.8</td>\n",
              "      <td>18.0</td>\n",
              "      <td>1447.0</td>\n",
              "      <td>297.0</td>\n",
              "      <td>788.0</td>\n",
              "      <td>281.0</td>\n",
              "      <td>2.6</td>\n",
              "      <td>1.5</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>50%</th>\n",
              "      <td>34.2</td>\n",
              "      <td>-118.5</td>\n",
              "      <td>29.0</td>\n",
              "      <td>2117.5</td>\n",
              "      <td>431.0</td>\n",
              "      <td>1173.5</td>\n",
              "      <td>406.0</td>\n",
              "      <td>3.6</td>\n",
              "      <td>1.9</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>75%</th>\n",
              "      <td>37.7</td>\n",
              "      <td>-118.0</td>\n",
              "      <td>37.0</td>\n",
              "      <td>3182.2</td>\n",
              "      <td>654.0</td>\n",
              "      <td>1738.2</td>\n",
              "      <td>607.0</td>\n",
              "      <td>4.8</td>\n",
              "      <td>2.3</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>max</th>\n",
              "      <td>42.0</td>\n",
              "      <td>-114.3</td>\n",
              "      <td>52.0</td>\n",
              "      <td>32054.0</td>\n",
              "      <td>5290.0</td>\n",
              "      <td>15507.0</td>\n",
              "      <td>5050.0</td>\n",
              "      <td>15.0</td>\n",
              "      <td>26.5</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "       latitude  longitude  ...  median_income  rooms_per_person\n",
              "count    5000.0     5000.0  ...         5000.0            5000.0\n",
              "mean       35.6     -119.6  ...            3.9               2.0\n",
              "std         2.2        2.0  ...            1.9               0.9\n",
              "min        32.5     -124.2  ...            0.5               0.1\n",
              "25%        33.9     -121.8  ...            2.6               1.5\n",
              "50%        34.2     -118.5  ...            3.6               1.9\n",
              "75%        37.7     -118.0  ...            4.8               2.3\n",
              "max        42.0     -114.3  ...           15.0              26.5\n",
              "\n",
              "[8 rows x 9 columns]"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "Training targets summary:\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>median_house_value</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>count</th>\n",
              "      <td>12000.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>mean</th>\n",
              "      <td>207.2</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>std</th>\n",
              "      <td>115.7</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>min</th>\n",
              "      <td>15.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>25%</th>\n",
              "      <td>119.2</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>50%</th>\n",
              "      <td>180.4</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>75%</th>\n",
              "      <td>265.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>max</th>\n",
              "      <td>500.0</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "       median_house_value\n",
              "count             12000.0\n",
              "mean                207.2\n",
              "std                 115.7\n",
              "min                  15.0\n",
              "25%                 119.2\n",
              "50%                 180.4\n",
              "75%                 265.0\n",
              "max                 500.0"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "Validation targets summary:\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>median_house_value</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>count</th>\n",
              "      <td>5000.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>mean</th>\n",
              "      <td>207.5</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>std</th>\n",
              "      <td>116.6</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>min</th>\n",
              "      <td>15.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>25%</th>\n",
              "      <td>120.7</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>50%</th>\n",
              "      <td>180.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>75%</th>\n",
              "      <td>265.6</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>max</th>\n",
              "      <td>500.0</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "       median_house_value\n",
              "count              5000.0\n",
              "mean                207.5\n",
              "std                 116.6\n",
              "min                  15.0\n",
              "25%                 120.7\n",
              "50%                 180.0\n",
              "75%                 265.6\n",
              "max                 500.0"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "hLvmkugKLany",
        "colab_type": "text"
      },
      "source": [
        " ## 任务 1：构建良好的特征集\n",
        "\n",
        "**如果只使用 2 个或 3 个特征，您可以获得的最佳效果是什么？**\n",
        "\n",
        "**相关矩阵**展现了两两比较的相关性，既包括每个特征与目标特征之间的比较，也包括每个特征与其他特征之间的比较。\n",
        "\n",
        "在这里，相关性被定义为[皮尔逊相关系数](https://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient)。您不必理解具体数学原理也可完成本练习。\n",
        "\n",
        "相关性值具有以下含义：\n",
        "\n",
        "  * `-1.0`：完全负相关\n",
        "  * `0.0`：不相关\n",
        "  * `1.0`：完全正相关"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "UzoZUSdLIolF",
        "colab_type": "code",
        "cellView": "both",
        "colab": {
          "test": {
            "output": "ignore",
            "timeout": 600
          },
          "base_uri": "https://localhost:8080/",
          "height": 359
        },
        "outputId": "27e59407-f65a-421e-d3ce-dbc6b398bb2f"
      },
      "source": [
        "correlation_dataframe = training_examples.copy()\n",
        "correlation_dataframe[\"target\"] = training_targets[\"median_house_value\"]\n",
        "\n",
        "correlation_dataframe.corr()"
      ],
      "execution_count": 5,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>latitude</th>\n",
              "      <th>longitude</th>\n",
              "      <th>housing_median_age</th>\n",
              "      <th>total_rooms</th>\n",
              "      <th>total_bedrooms</th>\n",
              "      <th>population</th>\n",
              "      <th>households</th>\n",
              "      <th>median_income</th>\n",
              "      <th>rooms_per_person</th>\n",
              "      <th>target</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>latitude</th>\n",
              "      <td>1.0</td>\n",
              "      <td>-0.9</td>\n",
              "      <td>0.0</td>\n",
              "      <td>-0.0</td>\n",
              "      <td>-0.1</td>\n",
              "      <td>-0.1</td>\n",
              "      <td>-0.1</td>\n",
              "      <td>-0.1</td>\n",
              "      <td>0.1</td>\n",
              "      <td>-0.1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>longitude</th>\n",
              "      <td>-0.9</td>\n",
              "      <td>1.0</td>\n",
              "      <td>-0.1</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.1</td>\n",
              "      <td>0.1</td>\n",
              "      <td>0.1</td>\n",
              "      <td>-0.0</td>\n",
              "      <td>-0.1</td>\n",
              "      <td>-0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>housing_median_age</th>\n",
              "      <td>0.0</td>\n",
              "      <td>-0.1</td>\n",
              "      <td>1.0</td>\n",
              "      <td>-0.4</td>\n",
              "      <td>-0.3</td>\n",
              "      <td>-0.3</td>\n",
              "      <td>-0.3</td>\n",
              "      <td>-0.1</td>\n",
              "      <td>-0.1</td>\n",
              "      <td>0.1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>total_rooms</th>\n",
              "      <td>-0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>-0.4</td>\n",
              "      <td>1.0</td>\n",
              "      <td>0.9</td>\n",
              "      <td>0.9</td>\n",
              "      <td>0.9</td>\n",
              "      <td>0.2</td>\n",
              "      <td>0.1</td>\n",
              "      <td>0.1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>total_bedrooms</th>\n",
              "      <td>-0.1</td>\n",
              "      <td>0.1</td>\n",
              "      <td>-0.3</td>\n",
              "      <td>0.9</td>\n",
              "      <td>1.0</td>\n",
              "      <td>0.9</td>\n",
              "      <td>1.0</td>\n",
              "      <td>-0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>population</th>\n",
              "      <td>-0.1</td>\n",
              "      <td>0.1</td>\n",
              "      <td>-0.3</td>\n",
              "      <td>0.9</td>\n",
              "      <td>0.9</td>\n",
              "      <td>1.0</td>\n",
              "      <td>0.9</td>\n",
              "      <td>-0.0</td>\n",
              "      <td>-0.1</td>\n",
              "      <td>-0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>households</th>\n",
              "      <td>-0.1</td>\n",
              "      <td>0.1</td>\n",
              "      <td>-0.3</td>\n",
              "      <td>0.9</td>\n",
              "      <td>1.0</td>\n",
              "      <td>0.9</td>\n",
              "      <td>1.0</td>\n",
              "      <td>-0.0</td>\n",
              "      <td>-0.0</td>\n",
              "      <td>0.1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>median_income</th>\n",
              "      <td>-0.1</td>\n",
              "      <td>-0.0</td>\n",
              "      <td>-0.1</td>\n",
              "      <td>0.2</td>\n",
              "      <td>-0.0</td>\n",
              "      <td>-0.0</td>\n",
              "      <td>-0.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>0.2</td>\n",
              "      <td>0.7</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>rooms_per_person</th>\n",
              "      <td>0.1</td>\n",
              "      <td>-0.1</td>\n",
              "      <td>-0.1</td>\n",
              "      <td>0.1</td>\n",
              "      <td>0.0</td>\n",
              "      <td>-0.1</td>\n",
              "      <td>-0.0</td>\n",
              "      <td>0.2</td>\n",
              "      <td>1.0</td>\n",
              "      <td>0.2</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>target</th>\n",
              "      <td>-0.1</td>\n",
              "      <td>-0.0</td>\n",
              "      <td>0.1</td>\n",
              "      <td>0.1</td>\n",
              "      <td>0.0</td>\n",
              "      <td>-0.0</td>\n",
              "      <td>0.1</td>\n",
              "      <td>0.7</td>\n",
              "      <td>0.2</td>\n",
              "      <td>1.0</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "                    latitude  longitude  ...  rooms_per_person  target\n",
              "latitude                 1.0       -0.9  ...               0.1    -0.1\n",
              "longitude               -0.9        1.0  ...              -0.1    -0.0\n",
              "housing_median_age       0.0       -0.1  ...              -0.1     0.1\n",
              "total_rooms             -0.0        0.0  ...               0.1     0.1\n",
              "total_bedrooms          -0.1        0.1  ...               0.0     0.0\n",
              "population              -0.1        0.1  ...              -0.1    -0.0\n",
              "households              -0.1        0.1  ...              -0.0     0.1\n",
              "median_income           -0.1       -0.0  ...               0.2     0.7\n",
              "rooms_per_person         0.1       -0.1  ...               1.0     0.2\n",
              "target                  -0.1       -0.0  ...               0.2     1.0\n",
              "\n",
              "[10 rows x 10 columns]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 5
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "RQpktkNpia2P",
        "colab_type": "text"
      },
      "source": [
        " 理想情况下，我们希望具有与目标密切相关的特征。\n",
        "\n",
        "此外，我们还希望有一些相互之间的相关性不太密切的特征，以便它们添加独立信息。\n",
        "\n",
        "利用这些信息来尝试移除特征。您也可以尝试构建其他合成特征，例如两个原始特征的比例。\n",
        "\n",
        "为方便起见，我们已经添加了前一个练习的训练代码。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "bjR5jWpFr2xs",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def construct_feature_columns(input_features):\n",
        "  \"\"\"Construct the TensorFlow Feature Columns.\n",
        "\n",
        "  Args:\n",
        "    input_features: The names of the numerical input features to use.\n",
        "  Returns:\n",
        "    A set of feature columns\n",
        "  \"\"\" \n",
        "  return set([tf.feature_column.numeric_column(my_feature)\n",
        "              for my_feature in input_features])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jsvKHzRciH9T",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def my_input_fn(features, targets, batch_size=1, shuffle=True, num_epochs=None):\n",
        "    \"\"\"Trains a linear regression model.\n",
        "  \n",
        "    Args:\n",
        "      features: pandas DataFrame of features\n",
        "      targets: pandas DataFrame of targets\n",
        "      batch_size: Size of batches to be passed to the model\n",
        "      shuffle: True or False. Whether to shuffle the data.\n",
        "      num_epochs: Number of epochs for which data should be repeated. None = repeat indefinitely\n",
        "    Returns:\n",
        "      Tuple of (features, labels) for next data batch\n",
        "    \"\"\"\n",
        "    \n",
        "    # Convert pandas data into a dict of np arrays.\n",
        "    features = {key:np.array(value) for key,value in dict(features).items()}                                           \n",
        "    \n",
        "    # Construct a dataset, and configure batching/repeating.\n",
        "    ds = Dataset.from_tensor_slices((features,targets)) # warning: 2GB limit\n",
        "    ds = ds.batch(batch_size).repeat(num_epochs)\n",
        "\n",
        "    # Shuffle the data, if specified.\n",
        "    if shuffle:\n",
        "      ds = ds.shuffle(10000)\n",
        "    \n",
        "    # Return the next batch of data.\n",
        "    features, labels = ds.make_one_shot_iterator().get_next()\n",
        "    return features, labels"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "g3kjQV9WH3pb",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def train_model(\n",
        "    learning_rate,\n",
        "    steps,\n",
        "    batch_size,\n",
        "    training_examples,\n",
        "    training_targets,\n",
        "    validation_examples,\n",
        "    validation_targets):\n",
        "  \"\"\"Trains a linear regression model.\n",
        "  \n",
        "  In addition to training, this function also prints training progress information,\n",
        "  as well as a plot of the training and validation loss over time.\n",
        "  \n",
        "  Args:\n",
        "    learning_rate: A `float`, the learning rate.\n",
        "    steps: A non-zero `int`, the total number of training steps. A training step\n",
        "      consists of a forward and backward pass using a single batch.\n",
        "    batch_size: A non-zero `int`, the batch size.\n",
        "    training_examples: A `DataFrame` containing one or more columns from\n",
        "      `california_housing_dataframe` to use as input features for training.\n",
        "    training_targets: A `DataFrame` containing exactly one column from\n",
        "      `california_housing_dataframe` to use as target for training.\n",
        "    validation_examples: A `DataFrame` containing one or more columns from\n",
        "      `california_housing_dataframe` to use as input features for validation.\n",
        "    validation_targets: A `DataFrame` containing exactly one column from\n",
        "      `california_housing_dataframe` to use as target for validation.\n",
        "      \n",
        "  Returns:\n",
        "    A `LinearRegressor` object trained on the training data.\n",
        "  \"\"\"\n",
        "\n",
        "  periods = 10\n",
        "  steps_per_period = steps / periods\n",
        "\n",
        "  # Create a linear regressor object.\n",
        "  my_optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)\n",
        "  my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)\n",
        "  linear_regressor = tf.estimator.LinearRegressor(\n",
        "      feature_columns=construct_feature_columns(training_examples),\n",
        "      optimizer=my_optimizer\n",
        "  )\n",
        "    \n",
        "  # Create input functions.\n",
        "  training_input_fn = lambda: my_input_fn(training_examples, \n",
        "                                          training_targets[\"median_house_value\"], \n",
        "                                          batch_size=batch_size)\n",
        "  predict_training_input_fn = lambda: my_input_fn(training_examples, \n",
        "                                                  training_targets[\"median_house_value\"], \n",
        "                                                  num_epochs=1, \n",
        "                                                  shuffle=False)\n",
        "  predict_validation_input_fn = lambda: my_input_fn(validation_examples, \n",
        "                                                    validation_targets[\"median_house_value\"], \n",
        "                                                    num_epochs=1, \n",
        "                                                    shuffle=False)\n",
        "\n",
        "  # Train the model, but do so inside a loop so that we can periodically assess\n",
        "  # loss metrics.\n",
        "  print(\"Training model...\")\n",
        "  print(\"RMSE (on training data):\")\n",
        "  training_rmse = []\n",
        "  validation_rmse = []\n",
        "  for period in range (0, periods):\n",
        "    # Train the model, starting from the prior state.\n",
        "    linear_regressor.train(\n",
        "        input_fn=training_input_fn,\n",
        "        steps=steps_per_period,\n",
        "    )\n",
        "    # Take a break and compute predictions.\n",
        "    training_predictions = linear_regressor.predict(input_fn=predict_training_input_fn)\n",
        "    training_predictions = np.array([item['predictions'][0] for item in training_predictions])\n",
        "    \n",
        "    validation_predictions = linear_regressor.predict(input_fn=predict_validation_input_fn)\n",
        "    validation_predictions = np.array([item['predictions'][0] for item in validation_predictions])\n",
        "    \n",
        "    # Compute training and validation loss.\n",
        "    training_root_mean_squared_error = math.sqrt(\n",
        "        metrics.mean_squared_error(training_predictions, training_targets))\n",
        "    validation_root_mean_squared_error = math.sqrt(\n",
        "        metrics.mean_squared_error(validation_predictions, validation_targets))\n",
        "    # Occasionally print the current loss.\n",
        "    print(\"  period %02d : %0.2f\" % (period, training_root_mean_squared_error))\n",
        "    # Add the loss metrics from this period to our list.\n",
        "    training_rmse.append(training_root_mean_squared_error)\n",
        "    validation_rmse.append(validation_root_mean_squared_error)\n",
        "  print(\"Model training finished.\")\n",
        "\n",
        "  \n",
        "  # Output a graph of loss metrics over periods.\n",
        "  plt.ylabel(\"RMSE\")\n",
        "  plt.xlabel(\"Periods\")\n",
        "  plt.title(\"Root Mean Squared Error vs. Periods\")\n",
        "  plt.tight_layout()\n",
        "  plt.plot(training_rmse, label=\"training\")\n",
        "  plt.plot(validation_rmse, label=\"validation\")\n",
        "  plt.legend()\n",
        "\n",
        "  return linear_regressor"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "varLu7RNH3pf",
        "colab_type": "text"
      },
      "source": [
        " 花 5 分钟时间来搜索一组效果良好的特征和训练参数。然后查看解决方案，看看我们选择了哪些参数。请谨记，不同的特征可能需要不同的学习参数。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "DSgUxRIlH3pg",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "#\n",
        "# Your code here: add your features of choice as a list of quoted strings.\n",
        "#\n",
        "minimal_features = [\n",
        "]\n",
        "\n",
        "assert minimal_features, \"You must select at least one feature!\"\n",
        "\n",
        "minimal_training_examples = training_examples[minimal_features]\n",
        "minimal_validation_examples = validation_examples[minimal_features]\n",
        "\n",
        "#\n",
        "# Don't forget to adjust these parameters.\n",
        "#\n",
        "train_model(\n",
        "    learning_rate=0.001,\n",
        "    steps=500,\n",
        "    batch_size=5,\n",
        "    training_examples=minimal_training_examples,\n",
        "    training_targets=training_targets,\n",
        "    validation_examples=minimal_validation_examples,\n",
        "    validation_targets=validation_targets)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "IGINhMIJ5Wyt",
        "colab_type": "text"
      },
      "source": [
        " ### 解决方案\n",
        "\n",
        "点击下方即可查看解决方案。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "BAGoXFPZ5ZE3",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 657
        },
        "outputId": "6635bc99-3709-4d39-bb96-115d6abfc389"
      },
      "source": [
        "minimal_features = [\n",
        "  \"median_income\",\n",
        "  \"latitude\",\n",
        "]\n",
        "\n",
        "minimal_training_examples = training_examples[minimal_features]\n",
        "minimal_validation_examples = validation_examples[minimal_features]\n",
        "\n",
        "_ = train_model(\n",
        "    learning_rate=0.01,\n",
        "    steps=500,\n",
        "    batch_size=5,\n",
        "    training_examples=minimal_training_examples,\n",
        "    training_targets=training_targets,\n",
        "    validation_examples=minimal_validation_examples,\n",
        "    validation_targets=validation_targets)"
      ],
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "\n",
            "WARNING: The TensorFlow contrib module will not be included in TensorFlow 2.0.\n",
            "For more information, please see:\n",
            "  * https://github.com/tensorflow/community/blob/master/rfcs/20180907-contrib-sunset.md\n",
            "  * https://github.com/tensorflow/addons\n",
            "If you depend on functionality not listed there, please file an issue.\n",
            "\n",
            "Training model...\n",
            "RMSE (on training data):\n",
            "  period 00 : 165.35\n",
            "  period 01 : 122.65\n",
            "  period 02 : 116.56\n",
            "  period 03 : 115.92\n",
            "  period 04 : 115.48\n",
            "  period 05 : 114.94\n",
            "  period 06 : 114.24\n",
            "  period 07 : 113.68\n",
            "  period 08 : 113.19\n",
            "  period 09 : 112.65\n",
            "Model training finished.\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\ndyUiItJJ8oZTSgD+/GVY+UC8KxERoba2ljvvvLPP651xxhnU1tb2uMyNN97Is88+29/S4iJ5w8kM\nxs+FrZHcE05EJLq6C6fW1p5vJfbEE09QWFjY4zLf/va3Oe200wZUX6wlbTg559hROBN2bYT9NfEu\nR0SS3HXXXcfbb7/NzJkzmTNnDieccAJnn302Rx99NAAf//jHqaysZOrUqdx9993t65WWlrJz5042\nbdrElClT+PznP8/UqVP58Ic/TEODd+PpSy65hEcffbR9+ZtuuonZs2czffp0Xn/9dQBqamo4/fTT\nmTp1KpdddhklJSXs3Lkzxu/CQUl7Knkw5PjK4kweSsFrPU05K94liUgC+Naf17F++75B3ebRo/O5\n6aypPS5z6623snbtWlatWsXzzz/PmWeeydq1a9tPxb7//vspLi6moaGBOXPm8IlPfIJhw4Z12MZb\nb73Fww8/zD333MOFF17IY489xqc+9alDnmv48OG88sor3Hnnndx2223ce++9fOtb3+KUU07h+uuv\n56mnnuK+++4bvDegH5K25ZQaSCF9/GyaSYMt2rUnIonl2GOP7XCN0B133MGMGTOYO3cuW7du5a23\n3jpknbKyMmbOnAlAZWUlmzZt6nLb55133iHLvPTSSyxYsACA+fPnU1RUNIivpu+StuUEMKP0CFZv\nmcCszYuT+40QkXa9tXBiJScnp334+eef59lnn2Xx4sVkZ2czb968Lq8hysjIaB8OBALtu/W6Wy4Q\nCPR6TCtekrblBDCntJjloQpS3l8DzfXxLkdEklheXh51dXVdztu7dy9FRUVkZ2fz+uuvs2TJ4O/t\nOf7441m0aBEAzzzzDHv27Bn05+iLpA6nmeMKecVVkBJqge2vxLscEUliw4YN4/jjj2fatGl87Wtf\n6zBv/vz5tLa2MmXKFK677jrmzp076M9/00038cwzzzBt2jR+97vfMWrUKPLy8gb9eSJlzrm4PflA\nVVVVuYHebHDB/3uCR/ZcDKd8E0786iBVJiJDyYYNG5gyZUq8y4irpqYmAoEAqampLF68mMsvv5xV\nq1YNaJtdva9mttI5V9Xbukl/qGVyWQlv7R7LxC2Lk7sZKSJJbcuWLVx44YWEQiHS09O555574lpP\n0odTVWkRy5eVM2HLMgiFIEURJSLJZ9KkSbz66qvxLqNd0v8nriopZkWonEDzPqjZEO9yREQEhROj\nCjKpzpvhjeh6JxGRhJD04QQwpmwKOynEKZxERBKCwgmoLC1mabCc4KaX412KiIigcAK8kyJWhipI\nrauGvdviXY6ISK9yc3MB2L59O+eff36Xy8ybN4/eLrf50Y9+RH39wU4IIrkFRywonIDykXmsS/N6\n/tUtNERkKBk9enR7j+P90TmcIrkFRywonICUFCNn/CwayIQtS+Ndjogkoeuuu46f/vSn7eM333wz\n3/3udzn11FPbb2/xpz/96ZD1Nm3axLRp0wBoaGhgwYIFTJkyhXPPPbdD33qXX345VVVVTJ06lZtu\nugnwOpPdvn07J598MieffDJw8BYcALfffjvTpk1j2rRp/OhHP2p/vu5uzTGYkv46pzaVZSN45d2J\nHLfpZb0pIsnsyevg/dcGd5ujpsNHb+1xkYsuuogvf/nLXHHFFQAsWrSIp59+mquvvpr8/Hx27tzJ\n3LlzOfvsszGzLrdx1113kZ2dzYYNG1izZg2zZ89un3fLLbdQXFxMMBjk1FNPZc2aNVx99dXcfvvt\nPPfccwwfPrzDtlauXMkvfvELli5dinOO4447jpNOOomioqKIb80xEGo5+SpLiljhKgjUrIOmrjtf\nFBGJllmzZrFjxw62b9/O6tWrKSoqYtSoUdxwww0cc8wxnHbaaWzbto0PPvig2228+OKL7SFxzDHH\ncMwxx7TPW7RoEbNnz2bWrFmsW7eO9evX91jPSy+9xLnnnktOTg65ubmcd955/POf/wQivzXHQESt\nkWBm9wMfA3Y456aFTb8KuAIIAn91zn3dn3498Dl/+tXOuaejVVtXZowt5OdUYC4E1cth4imxfHoR\nSRS9tHCi6YILLuDRRx/l/fff56KLLuKhhx6ipqaGlStXkpaWRmlpaZe3yujNu+++y2233cby5csp\nKirikksu6dd22kR6a46BiGbL6QFgfvgEMzsZOAeY4ZybCtzmTz8aWABM9de508wCUaztEFnpARqP\nqCREio47iUhcXHTRRTzyyCM8+uijXHDBBezdu5eRI0eSlpbGc889x+bNm3tc/8QTT+Q3v/kNAGvX\nrmXNmjUA7Nu3j5ycHAoKCvjggw948skn29fp7lYdJ5xwAn/84x+pr6/nwIED/OEPf+CEE04YxFfb\ns6i1nJxzL5pZaafJlwO3Ouea/GV2+NPPAR7xp79rZhuBY4HF0aqvK1PLxvD6zvFM3qxOYEUk9qZO\n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\nREQk4fx/Ap45EdLlKjUAAAAASUVORK5CYII=\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "RidI9YhKOiY2",
        "colab_type": "text"
      },
      "source": [
        " ## 任务 2：更好地利用纬度\n",
        "\n",
        "绘制 `latitude` 与 `median_house_value` 的图形后，表明两者确实不存在线性关系。\n",
        "\n",
        "不过，有几个峰值与洛杉矶和旧金山大致相对应。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "hfGUKj2IR_F1",
        "colab_type": "code",
        "cellView": "both",
        "colab": {
          "test": {
            "output": "ignore",
            "timeout": 600
          },
          "base_uri": "https://localhost:8080/",
          "height": 287
        },
        "outputId": "99b5952f-3b9c-4be0-e337-0f7ea7603b2c"
      },
      "source": [
        "plt.scatter(training_examples[\"latitude\"], training_targets[\"median_house_value\"])"
      ],
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<matplotlib.collections.PathCollection at 0x7f4621b5f2b0>"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 9
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAD8CAYAAAB5Pm/hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAIABJREFUeJztnX+UFNd157+3e2qgB3vpwR47UguE\nLGuHLEHMmLHBZk824FhjC0seC0lEFo6y60R7Nj82wtqJhxMSQItXJHNsydlks0eOvUdeZHmQkNvI\nOIt8VuRkQww24xlMsCCWLAnUKBEWDLGYBnp63v7R9Zrq6npVr6rrd7/PORyme2q6q7veu3Xfffd+\nLzHGoFAoFIr0kon6BBQKhUIRLMrQKxQKRcpRhl6hUChSjjL0CoVCkXKUoVcoFIqUowy9QqFQpBxl\n6BUKhSLlKEOvUCgUKUcZeoVCoUg5HVGfAAC8853vZIsXL476NBQKhSJRjI+P/4wx1uN0XCwM/eLF\ni3HkyJGoT0OhUCgSBRG9KnOcCt0oFApFylGGXqFQKFKOMvQKhUKRcpShVygUipSjDL1CoVCkHKms\nGyJ6BcDPAVQBzDDGBohoAYAxAIsBvALgbsbYeSIiAF8CcCuAaQC/wRj7of+n3syW4jE8cegUvLZS\nyec0EAFT0xVcm89heLAXQ/0FFCdKGN1/EqWpsq/n6xerb1yAV94s48xUGdfmc1izpAcHTpytP+af\nI40UJ0r4w28ew8UrVQAAAbh31SLsGFrm+TW3FI9h16FTPp2hHKtvXIAnfuuDgb8PH8vtMDYUVyGZ\nDlO6oR9gjP3M8NyfAjjHGNtJRCMAuhljnyOiWwH8HmqGfiWALzHGVtq9/sDAAGs1vTKIyZnTsli/\nooA94yWUK1VfXztMcloWD9+xLHUTujhRwoNPHUV1tnkMb/Ro7KMw8pygjX1xooTNzxxrGMtpHRvt\nAhGNM8YGnI5rJXTzCQCP6z8/DmDI8PzXWI1DAPJEdE0L7yPFk4dP+/6a5UoVTx4+nWgjD9Q+x+j+\nk1Gfhu+M7j9paeQB7+MhiHEky8GXzgX6+qP7TzaN5bSODUUjsoaeAXiOiMaJ6H79uXczxl7Xf/4n\nAO/Wfy4AMM6W1/TnGiCi+4noCBEdOXv2rIdTb6QaUO/boF43bM7ENOzUCnafyet1S8v1tkL0faVx\nbCgakTX0/5Yx9j4AHwPwO0T0y8Zfslr8x9UMYYw9xhgbYIwN9PQ4VvA6kiVq+TXCfN2wuTafi/oU\nfMfuM3m9bmm53laIvq80jg1FI1KGnjFW0v9/A8A3AXwAwD/zkIz+/xv64SUACw1/fp3+XKDcs3Kh\n80EuyWlZ3LNyIXJa1vfXDpOclsXwYG/Up+E7w4O9yGasDbPX8RDEOJJl9Y0LAn394cHeprGc1rGh\naMTR0BPRPCJ6O/8ZwC0A/gHAXgD36YfdB+Bb+s97Afw61VgF4IIhxBMYO4aWYV5nawY5n9PQ3aWB\nABTyOTx8xzLsGFqGh+9YhkKMvZ7VNy5AIZ+rn/fGVYsaHqd1s22ov4Av3LW84boTvG/EArVxtHHV\nIp/O0B13DQT7vkP9hfpYTvvYUDTimHVDRO9BzYsHaumYX2eMfZ6I3gFgN4BFAF5FLb3ynJ5e+ecA\nPopaeuW/Z4zZptT4kXUDyKdXFvI5HBxZ6+k9Vu98PtQ0y1aMlsIbVtkpbnhl5zrcMLLPdZpvK+NS\n0Z7IZt045tEzxn4KYLnF828C+LDF8wzA70iep28UJ0rYM16SmlytbD4ND/Zi09ik51x9t/BUP2Xs\nw8MqO8VIPqfhQrliOQYINYfDy/hQm6KKoEhNZazT5DSSIUJxwtu2wVB/ITQjz4ky5a8dcTK4F8oV\nPLKhD1a7Awzer5faFFUERWoMvRtvqMoYNj9zzLOxDzszI80pf3HEyeBmiGxXdV6ul9oUVQRJagy9\naHLmc5qlYW6lUCQKw9u3/TnPNyaFO6yyU4xUGbNd1ck6AvwwtSmqCJrUGHpR6ti225diVmCYvcZE\no8jAmSpXWlqFKOQxZqe4xU1K7tyOLB7d0IeDI2uVkVcESmoMvV3qmN+FIk4eHwDc9K55nl7bDlWu\n3kxxooT+h57D4pF9WDyyz/PKpzhRwuqdz+OGkX1YvfN5AMDBkbXSxt4qJdcJdT0VYZEaQw/UjP3w\nYC/m5zSUpsp4YGwS/Q89hzVLenwtFJHx+KavzGLjqkUQ1PN4RmVmXKU4UcJnd0/i/HSl/txUuYLh\np466MvY8nbI0VQYDUJoq11dPMt83V8wEgE1jk/UbhUwIR11PRRikytAXJ0oYfuoopspXJ/756QrG\nfnAa61cUfC0UGeov4ODIWsvMC6A2gXcMLcNPH17n+T2sUJkZV9m29zisNM0qs8yVp2wn9iXzfTPU\n0mDNNwqZvRx1PRVhIKVHnxRG959ExWLmV6oMB06cDaQY5dp8zrKAigG4cfN3fN24VZkZjRhv6Gbc\neMp2Yl+PbOjD8NNHUam6u46yqb5rlrSu86RQOJEqj95ucge1RB4e7IWWtfbr/TXyGaxfUcDo/pP1\nOLLamBXjxlMWHctQcx42vH8h5nQEM1UOnGhduVWhcCJVht5ucs/PacG9cQjZlnO1LPaMlyzjyO1K\nd5f4mrpZ+dhtrpemyhj7wWlcmZl1fX4yxLVrmSJdpMrQ203uIGqcihMlPLj7qGW4yG/OT1dU0wgT\nW29baqleuXHVIlf7L06b65Wqfd58K6RZFlkRH1Jl6O0m99R0YzzXnE7n1jMuTpQw/PTRyKtW2z1r\nwzyAtQxh4Hr3cr9Om+tBUWVMheEUgZMqQw+Ii5mM+jZ26XRmRDeE7c8ed71BFwSBhqRCxu3N12rz\n3W3GjZkosmBUGE4RNKkz9KJ4q1HfRrZ3pt0N4fy0OOMjTH5+eSYVBsLNzZcTRGs8mWK4IGg1DNfq\nClWRblJn6Hm81U7fRmQIzBtjohvC5md+5N8Jt0i1RQ82LnhpXB1Ea7yh/gLWryiEHsIBvN+gvNwk\nFe1F6gw9UJusdvo2IkNAQMPkEE28ciWYDAyvpCFzw4t33kprPDsP+MCJs6FLUQPeb1BebpKK9iKV\nhh6w9/aGB3uFWuLGyZGUqkUCEr9s9+Kde22N5+QBR7HB3UoxXBAhLEW6SK2ht/L2CLVJPbr/pNBj\nM04Okcfot35Nq3BjleRlu1fvnGfLvLxznbQKpJMHHOYNnlCT0p6rZeo6OW6vXRAhLEW6SK2hN+dG\nE67WNZWmysIYrHFyiDzGD77HffpemCRx2R5m42onD7hVmYmODEnXbXR1ZnHx8gzOT1c836hbCWEp\n2oNUad2YGeovYKi/YNnQm6HR+APWk4O/Bqc4UcIPT10I7qR9IonLdvN3HRQifSJ+kx/qL+APv3kM\nF694aw4+46KAzuo9+I1a9rvgx/FEAx6eVBr3Ck6qDT1HZPQYapWJVcZQkJwcbnrT+o2WJXRkqL4Z\nzCUArFI91bJdzPBgLzY/c6zhOhpv8sWJUmCSB7K4vVGHdZNUJJPUhm6M2Bm9KmP1SS4zUaL0lCtV\nhrlath7e6OrswLqbr2nbZbvX3HGnMJFIBTVM8jY6PgqFW9rCox8e7LWVmnWzVBYt+8Pi/HSl7sGX\npsrYM17C+hUFHDhxtq2W7TxzhnvlPLYN2EthcOw84DiEvVQ/eIWfpMrQ86pXbvDWLOmpG0CnChjZ\nyT082ItNY5OR5FlbUa5UA9PajzN2mTMy6ZV28eyob+ZATWt/9c7n2+KmrQie1Bh6Kw9v16FTVw9w\nsMzm8I7IGAz1F/DA2KTfp98ScfBAw8Zt7ji/njzjypiBZV4JWMXwo8DtKkWhEJGaGH0rm6TmmLZT\nQY1sw2i/0QRXqx03XkWf2ShexzFeT6D5nm9OR+Ux/LCw09ZJYqqsIn6kxtB79Wq7u7SmfG1RWGDT\n7lqzcVEeftB1VFo20/Qe7bLxakZGvI4j4wSYx89Qf8G2sYmfODWab8cVm8JfUmPo3Xq1hXwOG1ct\nQldnR1NFojAdk11NZeR5+EDtZqFlKPC4/XRltuE9CMD6Fe2ZVicjXseRMZTmLJfiRAlvXZpp/UQl\n4NW9ImPfjis2hb+kxtAPD/ZCk9QmIP14UWs+2YnFULthdHV2RJKOx9DePUedxOs4MtfzrUszTauA\nsK+pqnBVBEVqDD0A6dhJhggPjE0KszbcaJKfmSpHmqHR7st6kRE3eugy19PcsCSK7zVMGQhFe5Ga\nrJvR/SelOz7Ztf87M1WuT6wHdzu3Cpyf0zBVjq4JSbss60VZUKIaCe6hG/Pl+d/LCNrlu7TQmsvw\n8wTcV7g6pYoqFIALj56IskQ0QUTf1h/fQESHiehFIhojok79+Tn64xf13y8O5tQb8csDM+qdfOHu\n5baeYE7LBtJ0XBYCsGZJT3QnEBJ2WVBD/QXM62z2V8weulHl0q7d5A0j+9D/0HO4EGIHMa9qo6rh\niEIWN6Gb3wfwguHxnwB4hDH2XgDnAXxGf/4zAM7rzz+iHxc4fni25ngoX0rnLfqy8o1Qc9PxMGEA\n9oyXUj+x7YqjihMl4YrK6uZfnCjh4mXrTdYqY2CobbiHqXRTrlSx/dnjtsdYyT2ohiMKWaQMPRFd\nB2AdgL/SHxOAtQCe1g95HMCQ/vMn9MfQf/9h/fhAcbMZa4Uog2Wov4B5c5o9RgZg16FTyETp0qM9\nJrZd60deUGSFVRHc5meONd0Y4tBf4Px0RXjDFnnuor2hdt+3UTQj69E/CuAPgLqj8w4AU4wx7hq9\nBoBbyAKA0wCg//6CfnygDPUX0NnhfW/ZLoPFbuI4xfDD4MxUOdXNoUWrtSyRMD/eKltFlE8fsX5Z\nHdENW+S5W6WWAle/rzSPCYU7HC0jEX0cwBuMsXE/35iI7ieiI0R05OxZf1IEZfTDb3rXPOHvRAY9\n7hueXZ3ZVMdqRWmHdjdZq2yVuHu6bmUduPKqEX6DU/F7hREZF3g1gNuJ6BUA30AtZPMlAHki4jGN\n6wDwEVQCsBAA9N/PB/Cm+UUZY48xxgYYYwM9PeFtKL74xkXh70QGXTbdMifSKAiY6SvVVMdqRWmH\nosrVQj5nmXkS9xu225aA/HuwSsfctvd4qseEwh2O6ZWMsc0ANgMAEf0KgP/CGLuXiJ4CcCdqxv8+\nAN/S/2Sv/vh7+u+fZyyc+EZeItXR7kREhSnG9Dy7nHneECRsZNIFk45Vpy+rytVshoTXcc2SHjxx\n6FRslEfNXLw805BqybFrlGKVjul2g1qRflpxQT8H4LNE9CJqMfiv6M9/BcA79Oc/C2CktVOU5+PL\nr2np7+3yj3nOdisbvkHhFKtNI6LK1eosw5FXzzU9X5woYc94KbZGHqhJE1uFV9wWUtl57WkeEwox\nrgqmGGN/A+Bv9J9/CuADFsdcAnCXD+fmGhk5AHOf2PrzEvY7Dp2HrFj1nm788NQFYWu8NGLnmT5x\n6BQGrl/gKFQXR0Sa+m4KqexWnWkeEwoxqamMBewHOGAf2pEJLsV12fvKm2U8fMcyXyokk1Jpadcc\nhAFNxjKu184KmXMVNdmxmwPdXVosr6UieFJl6HmjbxEfX34Nnjx82vIYUfjDSBw6D1nBZRtancSt\ntucLE6dOX2Zj6ebadXdpmPjjWwDUvhO7NpRB4BRecWyyYwEB2HrbUr9OUZEwUiVq5pTTfuDEWeEx\nMvnww4O9gWvOe8GvRtJJqrQc6i/gQzcuEP7ebCytMqeyFvstOS3bYBC3P3s8VCMvE3LzEoZiiN/N\nWhEeqTL0Tp2fzkyVhZ67jEc/1F+I5WaeWWLXK27zuKPmlTetz4vLUBsZ6i9g/YpC/ToTAeZkMGN1\nNC82CkvYDKiNQRm1Si/XI6quaIp4kCpD75TvPj+n2Xr0MsYyjhPGLODlFbd53FEjbBCDZu+VZ93w\n689Yc0Usr442tx4Mi3tWLpTyut1ej7RvzCucSZWh516bVQakliFcvGLfMeizY5OOxt6NVn2YlKbK\nLZe6J63xhV0hkRnZcMeZqXJkGTqyTWRkxiCfAkrTXgGkbDOWe21mTy2f00AEx2X4LIBte4875tND\nPy5KHXorjKXugPuYrFm3Pc5ZN0CtAMpqE9JKulk23BHlhrvsOVpdJ551k4TrpgifVBl6kSfmxiA7\nHcvT2i6UK8jnNFSqs1IaO2EiysWWwY/snbAQecBWz8sYcB7bl2k4EwRuQjJJuk6K6EmVoQ9609Cc\n1jZVrsQyCweI7waqn4gMt9XzVjICZnhs/4GxSb9OUZqomshY1U0AyVnVKeRIlaH3Y9ltFMoyT4Jz\nFy836dnEMQsHiO8Gqp+I6iasMqi4obIz4lFutPMmMuaK3iCxyscffvoowFCvAI9zLYVCnlRtxrrx\niERCk+turunlWMm8RiVa5pY4b6D6iduaCCdDFXVbxrBrFqxCnZUqa5L5iGsthUKeVHn0slkLAPCu\nf2Xt/T95+DQGrl+QGG0UM4U2WmoXBCs4O89c9DdATSMnasIMubl5r3YIBaaZVHn0soMxn9NsmzlE\nkUPtBwTg4MhaX418nLsUeUkHtUtN5O0hoyRD5Pgdi66J22vlJrzXDqHANJMqQy8zGLUMYdvtS22P\ntWvTFmf8noxx71Jk1bx9rkPzl6H+At63aH7Qp+YZ7mi47R+7pXjM9bWyuulpWWqS4m6XUGCaSZWh\nHx7shZYVG+gsEUbvWl7XlrcrOrFq0xZnNJuGG15JivbN5Zmreyfnp6013TnFiRL+/qVmvfo4Yfcd\ni67Jk4dPu75WVjr3o3cux+hdy6W17xXJIFUxegC2AlSzjNUH7FB/AUdePSdcqvNYN8+66erMxi5f\n3sjb5nb4PhmToH1jdzOy+j5G95+MbaaUEavQYXGiJAwpijagna6VKB9fGfZ0kSpD7+Rp8tAGT5t0\natBgnAQ3bv6OfycaAE5Vv1505kXpqnGK17q9GcXpJmWHOXTI5ZLdEqdrpYiOVIVunCbx8GCvtGCV\n2QhGUSnpBgJcx3W96PrELV7rVogtKYbPPN5G9590LZcct2uliI5UGXq7SUxUM97bnz3uKW0y7puz\nvKuSFW5i7cbMjdH9J/G+RfPrnz1LVJfxjQtub0ZrlvTEtprZiDlF1O1KpLtLU7F1RZ1UGfrhwV7h\nB7p35SIUJ0qe9cXvWbnQ+4mFRKthDCvP/+BL5+reZZUx7BkvxSbrBnDXODsJDcKB2uqsNFWup0gW\nJ0rIuHQ0ujr937NRJJdUxejtNlh3HTqFZ8Zfk3odqzm1Y2hZ/XXiyvycdacp2Vi7TJFYK4JpQSEr\n8JWUIjh+I+KSBNVZ1qTI6kRS9iIU4ZAqjx6wr46dlpQwEIXjdwwti/WyX+T02YU3jKEa2SKxpBqR\nJJ53pereyAPJ2YtQhEPqDL0fk9muhD7OE2hKEJYShTcANIRqZInzd2BHUs9bhN2+0eJ3pOuzKloj\ndYZeFL6QpZUS+qixM2RD/QUcHFmLl3euq8skeAllWPVjTQpW1y5OKzS3+/2dHeI/+PuXzsVqL0UR\nLamK0W8pHmup61M+p2Hb7Usd472XYxjn9ZJK52X1I+rHmgT9cmNnppLeKD5OabNuT8VOTZVnYcXx\nOijCJzUefXGi5Iv6oN3E4FkpcRMr9lqmLloBdHdpQk/XHNaKux6OGaP8RZyMvJEsEQitp/QmcU9C\nEQypMfR+lLZPlSu2BiquWRtePWjRJu3W25bi3lWLmoy91aohKXo4RuJ6HTmzjOHlnetaTulN256E\nwjupMfR+eS9mA+UlKyVsvBpV8yZtPqdhrpbBprFJHDhxFveuWuSYn55EqYE4nxtQM9A851+GeZ1Z\nqZuyon1JTYzeTRvBfE4TxvKNRsDcai2utGK4eA66VVu5PeMlx5BQEvRwzMy3uf5Rww207Kojp2Xx\n+U/WMqjc7pMkZW9F0TqpMfQyzZ85F8oVdHdpllWyRgMV9yU+J9+lYfXO51uasG5VIDlW33vcvclK\nNW67LFfhEhMyDcqzRA03YjfX3OrGrnrDppfUhG6MYQgnrs3nsPW2pY4aKXFf4gO1RhFvXZpp2Ax9\nYGwSfdufc7Uh6jUE40aCIA5sKR6Ltdz0rkOn8It/9NdSx1YNsttuSeLeisI7qfHojctQLQPYFcEa\nPV67paubcFAUZAiY19lhGYaYKldceWithGBkJQiipjhRirWEBcdNE/r+h57D1tuWAnAXukni3orC\nO46GnojmAvhbAHP0459mjG0lohsAfAPAOwCMA/g0Y+wKEc0B8DUAKwC8CWADY+yVgM4fQPMy1Gme\nGJe6bsMScSGbIXzhruXYZLPEd6NLk8QQDEc21pxGb/X8dKWmU8+Aiq6VIBOGSeLeisI7MqGbywDW\nMsaWA+gD8FEiWgXgTwA8whh7L4DzAD6jH/8ZAOf15x/RjwsUr7F0p2bKQ/0FrF8RT0+1Ostw5NVz\njhNT1kOzk0mIa3NwQD6P3647k5nurtaqq8OmUmV1I88pV6p4cPdR4fVKQq8BhX84evSMMQbgLf2h\npv9jANYC+JT+/OMAtgH4SwCf0H8GgKcB/DkRkf46geBlubmleKxhGc+VAjm8ejJOJfJmdh06hdU3\nLsC5i1eENzo3Hpp5hZOEDTuZTWT+OWTQsoStty3FZ3dPehITixO80TjQfL1kQpeK9CAVoyeiLGrh\nmfcC+AsALwGYYozN6Ie8BoCPkAKA0wDAGJshoguohXd+5uN5N+Amlk4AFo/ss/xdpcrwuT0/wpWZ\n2XrxVdzn+sGXzmHjqkXY96PXm7KI3HhoVuEPr5k4YSITa5Zd8WWJsOH9CzG6/2TijTyHe/aAtbGP\ny3VUBItU1g1jrMoY6wNwHYAPAFjS6hsT0f1EdISIjpw9K5YWlmF4sBdaRs73dpq/lw1GPik8efgU\n/qU80/Ccm+wXUfhDdPOM0wa1TMtA2RUfb6wSp8/nB9yzj1vYTREertIrGWNTAA4A+CCAPBHxFcF1\nAPgoKgFYCAD67+ejtilrfq3HGGMDjLGBnp4ej6d/lfhmRgdPlTX3GF2zpEfaWxN57iLi0FaR76+I\njLJRplc2fJUh+8+dZFTqZHvjaOiJqIeI8vrPOQAfAfACagb/Tv2w+wB8S/95r/4Y+u+fDzI+DwDb\nnz2OalrW2j7x5OHT0se63eOIWgxMpsE7l+ktTpRw8fKM8DgjaR9CKnWyfZGJ0V8D4HE9Tp8BsJsx\n9m0i+jGAbxDRDgATAL6iH/8VAP+biF4EcA7ArwVw3g147QObZtwYY9Eeh0jGN0uEG0b2RbaBJxNz\nZ6g5AJcqs6n10t2iUifbF5msmx8B6Ld4/qeoxevNz18CcJcvZ6fwjJvwiiiHfv2KAvaMl5oMJTf+\nUWXhyHqm7eIAEGr6PRfKFVybz2HNkp6m69bqxrzatE02iZdAUBtM1riRuBXl0O8YWtbwvNW9I4rY\nb6tdxNKG+doMXL/AsyxF0voLKOSggMPnUgwMDLAjR454+lu7Dbl24aZ3zcNPz06jyhiyRLhn5ULs\nGFrm63sUJ0pCoS0C8PLOdb6+n915DD99FJWq87jNaRlXcgJpQctSXRqDh98Kkp65aD51d2no6uxQ\nXn7MIKJxxtiA03GJ17pRG0zAz966gpcevrXl17Fbstt57WHGfkf3n5Qy8kDtBpTTsk0hjLTH7CtV\nVtc/MobZNo1N4oGxSVujL5pP56cr9VBYHAvnFPYkPnQTlpGJQ0qhiFZi0TxNcfHIPmwamxQu2e1u\nqNNXZkKTSHBzY5+uzAplHdoRfnu0C8fIzieVrpksEm/ohwd7oWWDN8Kr3tMd+HsEiZWujzlN0ewn\nGyeznQE4P10JLZ7r9sY+1F/AwZG1eHnnOhwcWas8UB2RobbSwBGhVtPJIfGGfqi/gHmdwUegfvz6\nzyFZfBs7RBts25897hjG4JPZygBYfR1Be3puRLeSJk4WNlaG2mpjPi/Y/Fbpmskh8TF6AKG0hYt7\nqp5dhylR5atMrJpPZisRLNEmeJCe3lB/Adv2Hpe65utuvqbpueJECYT4axiFgchQO4nbAUrpMmkk\n3qNX1DB668NPN8rTejW8TpNZ5DEH7eltu725O5gVB040ayiN7j+pjDzcGeqkdRFTNJMKj17RSKXK\nsP3Z4/WJKPK+nTxb42S2kizWMgQtSw1ZMGF4eubVhegzWN3g2j0VlwBP6ZFK6TLZJNrQ83RARTPG\nUJOoU5adkZ/XmcXo/pPYNDaJa/M5TF+Zafr7yixDPqdh3pwOlKbKyBI1xOiDNAzc8BQnStg0Nmn5\nWVQMuRmVA9+eJDZ0IyNspajBl96yKaLZDOHKzGxDOEi0R3GhXKlv1JqlEcKophSFYgiNG7c866jd\nUZWu7UliDb3X9oHtylB/AbM2VdDG+Ovb53Q0taYTcW0+Z9ugJGhE+w8MtTFilUaadjIAHt3Qh4Jg\nRaNy4NuPxIZuVA6vM6t3Pt+wTBfF6gv5HA6OrK0/vkHQgcuMliVcvDwjzIAJ4xrZZf9w73VOR6at\nnIJZAA+MTQrTIgE1f9qNxHr0Kv7qjHmZLtsQOm+Tf076v+4uDWD2qa0ZosBDBE4bv+VKNZT0Wz/g\ndRp+VWHbfW41f9qLxBp6NxV87Yx5c1QmTc5O546hJmDW1ekc3gmjhV2aNhVnWW1/xO/GLubbhsqB\nbz8SG7oxpti1S+zVK8Zlukya3AUJD1h26R+3ZuJxJ4hOaQy1m7qs8qTSo08fiTX0wFWjdcPIPlUE\nY4PbZbpd3NvNMRwVD44eWWNtVS+hlCqTT2JDN0ZUvFGMl2W63fE5LVM/Rkb7BlDXJw48MDaJLcVj\njsdFmUGlCI5Ee/Sc4cFeDD91VDolsF3o7tKw9bal0p6ccbnemSVcsdB9n6sbdyvtm1Zb2CmCZdeh\nU9h16JQnPXq1Kks2qTD0QC2lTHGVfE7DxB/fInWs1XJdxJShcMoq3j9w/QIV3405duEYUUhOrcqS\nTSoM/fZnjweyiZVUuD7/DSP7pIytm+Izu9RLIBhNFLU56D+iTXJRo3i1Kks2qYjRx11COGx4KznZ\nZiBuluXnpyuhdJLiqGbVwSGrR6+UKpNP4j16NeGdMW6mGbXceQzfTQYNEG4mhmhz8MHdR+uCa37q\ny/Nm2u2AORxjXjk9sqFPGfhSy98DAAAgAElEQVSUkHiPftve41GfQiIoTZUx/NTRhmrJ89MVDD99\nFGuW9LguPotay6bKWN3Dz/jY+usX5s/17bXijJXom1o5pZfEG/qklLdHDREss5IqVYYDJ842LNe7\nuzSptolhadk4UZ1lmNfpT5V0uxTf3btqEQDU+wg/uPuoSqtMMYk39Ao57KIRZoPd1dmBT61c5Gg8\nw8jEkJW6uHilfUTL/MLowYvCVSqtMh0k3tD7pP/U1uS7tKZl+9gPTuPKjH3SammqHPjGrHlz0C/B\nr3Zn16FTUplWYQjTKYKHWAw2ngYGBtiRI0c8/e1iSUnddief03Dx8kxT+EbLEuZ1drQUAstp2dAy\nM6waVSuChY+RC+WKSm+NGUQ0zhgbcDou8R69qLmC4io5LYttty/F6F3LGzTKu7s0jN65XErEzI6w\nY7lzOhI/bBOF23RdRfxIfHqlqB+q33R3aYnM1zeXu1t5Yn4ogIYRy7Xy5v1MrVTIoRRJk0fiDX1Y\ncsWXKskTWeju0qSW2WuW9OCJQ6daMpgZIulKXDcYc7szFjnuyshHg9qkTRaJN/TAVWO/afekbXaJ\nVwiwXDHEpbgmA2utn/PTFcfCpuJECXvGSy0bTHNjcLv3lMXswdt91xmqNe5QhIPSvkkWjsFOIlpI\nRAeI6MdEdJyIfl9/fgERfZeIfqL/360/T0T0Z0T0IhH9iIjeF/SH4AYhKJsretkqY3VdmSixW2vw\nZXZxolTPmTZmygTRZN2vmL3suRXyOXzx7r6mNMw4XJukYqyp0ExFFUr7JnnIePQzAB5kjP2QiN4O\nYJyIvgvgNwD8X8bYTiIaATAC4HMAPgbgJv3fSgB/qf8fGEEYKxkKujTvrkOnQn9vN3Av26qZRFBL\ncD9eV+Y1uNGxkk22a1yucIZLIHgVlYtCjE4J4FnjaOgZY68DeF3/+edE9AKAAoBPAPgV/bDHAfwN\naob+EwC+xmp5m4eIKE9E1+iv4zvFiVLg1YxzOjLIEFkq+iWhcjBrOnfgqtc9P6cFYgzn5+xVLmUQ\nafBkiTDLWH0iA7UKT7NGyw0q9dYzpakyHhibxPZnj2PrbUtxcGStq7+PolOV6o4lxlWeGhEtBtAP\n4DCAdxuM9z8BeLf+cwHAacOfvaY/5zv8wgbN5ZlZrF9RsFT0i3vJfE7L2lY9iuqP5nVm0e0gSWzH\nxSszLafgWVXF5rQsvnD3cry8c13d+JiLvTaNTWLxyD5kVHFVy/B9HrfX0o9OVaJwY5DvmVakN2OJ\n6G0A9gB4gDH2L2SYRIwxRkSuIuREdD+A+wFg0aJFbv60TpghmwMnzlp6NXHZkDXCUw55auXmZ36E\nskXW0Fwt09BIxMjFK1VoWTk/YE5HBpdNVbSVKms5Bc8qHGNeiluNAX414nZdkkq5UsW2vcddXctW\nO1V58c5VdywxUoaeiDTUjPwTjLFn9Kf/mYdkiOgaAG/oz5cALDT8+XX6cw0wxh4D8BhQq4z1cvJh\nXkBe7m82NHEwJt1dGro6O4TG8LO7Jy3/rlyZFdYHEOQE4/I5TVhw5cf1cWpkEvcVVVqYKlewpXgM\nO4aWSR3faqcqO+9cNB5UdywxMlk3BOArAF5gjH3R8Ku9AO7Tf74PwLcMz/+6nn2zCsCFoOLzYV9A\nY1ig/6Hn0Lf9uVDfX8S6m6/BwZG1eGRDHwBg09hkw1LXLu3wrUszls/L3r623b5UeB3CuD5K+yY8\ndh06hcWSYRRR2E02W8eLd97qe6YZmbX5agCfBrCWiCb1f7cC2AngI0T0EwC/qj8GgO8A+CmAFwF8\nGcBv+3/aNaK4gNwAnp+uxCaj48CJs5Z64pvGJrGleMzWGLbaUH10/0lLPfuwJlgcVlTthowMQqud\nqrw4D6o7lpjEi5r9mz/6a0wnsGrVb/KC7BkC8KEbF+DgS+cCff8uLYM5WhZT0+EKX63e+bwK30RE\nIZ9znY0ji5XcRZjieUlBVtQs8ZWxysjXpJpFqwsG4JU37Q3hvM5sk557BgBcVJtOV2bBQKG3nxse\n7MXw00dRqUbvsLQbQe6RyWzEK+RJvKGPY9ZL2Dh9/DNTZRRs+sJaNe2YBVwLyUQmdtXelz8ygt6D\ncdqIV8iTaL3X4kSp7Y28DNwbMsfRCUBO83cIhJ3KNrr/ZMv7DAr3aFlSm5wJIrGGPqxiqbgjo+fC\nl7zmjapHNvT5rsqZb6HIygsqRzoi1L01USTW0EelbxM3Ru9cbtvbtbtLa9CiPziytl5VOtRf8H35\n/dal1iti3aBypKOhMstUxWmCSKyhV55cLfRy5NVzto2xt9621PY1hgd7fR0EYRuA4cHeQFQqC/kc\nbnrXPN9fN02oOZgcEmvolSdXWz07KWc+YCqeMjPUX8AXN/T5Gqv32wDYaZ4M9Rcwr9PfnIKclsWa\nJT147fwlX183bSR5DrrV0Uk6ic2jV02i3WFsAs4zlcxtBoHa97pt73HHYjC7Fn78df1IjbPLpwb8\n7yxmPHeVny9GyxBG71qeyKyYNOXopz6Pfqi/gCOvnsPXD59SnYUk4A2egeZuUEdePYcDJ86iNFWW\n6sFql9LKvWG/5GJFmifb9h7H5ZlZX2/0BNQLgDaNWesDKXQE0TKRHnycdOK96OgkncSGbooTJYx9\n/3QkRj6nZbFx1SLkfdBcj5pypYpdh07VvVenr9NO9hioKWLuOnTKN7lYURhoqlzxfTVnDEUkOSwR\nBlyd1IiVDMfmZ45hS/GY5fNRhUvaUeUysYZ+297joeVPE66KZ2WJsH5FATuGlmFy6y2hvH8cMGqH\nFARGkABLJUyOl1BIWAZXyzTmhVvVHSgaMRtGkaf85OHTsdKJj1KELyoSG7oJU1CM4Wq4o8oY9oyX\nMHD9gtQu88xYaZqYY5yyIR+31PT0m+Opc7WM7U3FLW+b29FwPfnPD6gQjhBzzYTII7ZrfOM3diEi\n/jurEGXaVS4Ta+ijxBjPs9KJSRPGCWCcRPNzWr1xiUgH3IyXKma+F/Pk4dOoMlZfUQ1cv8DXzXhR\nAxaFmPPTFfRtfw7bbl9ar8lws2rzy4MWGXDj3hCABk0k40i0SkpIG4k19ETOGi9BcmaqjOJESe/C\nlE5DXzBtphkN61S5gpyWrYuYyahIikI+dmwpHsMTh041dI16Qk8pffiOZdg0NulLkaaV0VEFQc5M\nlSt1Y2q1+hLhlwdtHpfmscCdsukrM5bCd91dWmAKnHEisYY+6qzQuVom9emdxgnglKkwPNiL4aeO\nCvdNvEzs4kSpwchzjPUDeUGHLLesWdLT0GB8eLA31ZtzfsLHAR8vTqmpfFXmhwctUyF/Rt8EtsLP\n8F+cSayhl4kJB8nlmdlUp3WavW+R0StNlXHj5u/YhmW8Lo1H95+0vcZWNwEvzOvMYs94qSEddPip\no5GvGpMEHx9ccdJuTPi5zyVzM5YJKcUp/TMIEpt1E/X8S7ORB2oerpH5NqmkTkae6+q4oThRcpyc\nDK23EsxQTabZ7BVWZlnqr7GfmMeH036MX1k3MnH+NUt60CWo/O7MkjAtNE3Vsok19IpgOXDibMNj\nr/bUS/jj3i9/TzrbpVWZamXM/eHilatidsWJkqieqgHR2HAjTyCTBnvgxFl0dlgfc6XKsG3v8Vil\nfwaBMvQKS8yT0GtWitvMii3FY67aHqrm4PHAWEDlFHLjWI0Nt961UX5bRGmqbJuOLfpdmvZolKFX\nWGKehF5T4dxuwD55+LT0sU5Vuopw4YZRxkCKNuftNv1FcPltu0I+L6SpgCqxm7GKYDFOwi3FY56q\nWvM5TRibF21+yRpuAjBTTW/GUxLhhlG0+ZnRN7ftNjvdyhMYx1G+S4OWoabML6cR1d2l4VJltqko\nL00FVMrQtwl2PWPNGJuVbCkes5VC7tIyuGSRgZTTsth2u7UWvjn32VjYItsDmAEIqi98BnrPXIUQ\nu8rSNUt6rMcMg2PzeNFNwioZwDyOzk9XkM24898JwLqbr8HA9QtU1o0i2WgZSBeF5LRsQ7MSp1DK\ndGUW18yveXI8Xs41cUQTxW55fs/KhVLnGSTKyNtDAD5044J6qCRLVL9+xYlS00Y+ZxbORWjDg73Q\nLIy1cbOXYzWOqi531xmAPeO11zV3X0sTiTX0Ue/B8UYdUZ+HDJVZ4IaRfY7HWRloGe+ae2BVxuqe\nnd1EsVue7xhaho2rFqlN1hjDAPzw1AWsWdLTsE/CV2Z2K0en+P1QfwFvm9scaOCbvcaMHL/6BaQt\nw8aKxBr6D71nQSTv292l4dENfXj4jpuR07KJKaiROU0rT8blSlhq0jipB+4YWoaXHr7Vk2SCIhzs\nVCntbtJ29RgcUYaX8Ubi97RLU4aNFYmN0b/yZrgXprtLw9bbltYN4eqdz6dK/sBYT2Lc4PIyoZwm\njUiR0rz5pTo8xRu7ylcRlWotMGZXiSqK0/MQURCElWETVQVuYg192Hfg89OVhi5JafMAOrKZujBZ\nq/ISGapVG1oNYD7QuednbmlonAhhkSFVOOUn+ZwmzE2/eKWKLcVjTZITxrklcgSCMvJhZdjYJSEE\nbewTa+jdSqL6gTEskZHMDkkK5cqsdJcpJ6qMWQ5g80A3xvQBoG/7c6H2GeAoI+8fOS3ruG/FJaeN\nGAXy+Jgxpk0yhkAMfZgSxVG2MExsjH54sBdaNvwNO34XTpORDwKrWL1ooG9/9jg2P3MsEiOvaB0+\nC/lmvlMVtUwjEl4E9ciGPrx1aSaQscFbgW4am3SUWvCDKFsYJtbQD/UXsOH9Cz1XvXklyDhh2jCv\nuEQD+vy0//1fFeHB0Che5zXebfV3QbUM1TKEi1dmQhUyi7KFYWINPW8OHqZfrUru3WFewqeppFzR\niPEmLhPvNq/GRXFyO0/eKt9exLzObN2DJ9TUSc2NSIJIszSmg168PCP9uf0msYZ+dP/J0JqDA1eX\npd1dzulhihrme6KV0mBOywolZBXJwXgTl4k3z+vsqKfPEtWM7ANjk+h/6Dl5r5rkdWzyXZ3YdvtS\naBmydQ79DKOYBdqmypWGm0s+p9kWFvqJ4wwjoq8S0RtE9A+G5xYQ0XeJ6Cf6/93680REf0ZELxLR\nj4jofUGdeNhZL3zDRjn07jBOWqPSIKF281y/omDZ4k2RHMx9hVfvfN7xb6bKlXoVrHFOnZ+u4IGx\nSfRtrxl8O8eqUmXSK/rSVBkP7hZ3QOP4uep06n518fKMb+/lBDEHy0VEvwzgLQBfY4z9kv7cnwI4\nxxjbSUQjALoZY58jolsB/B6AWwGsBPAlxthKp5MYGBhgR44ccXXiMj1K/SSnZX3tUZoWnLow8e9N\nlGr54O6jKhyWYPI5DUS1Iqf5OQ0XBb1ZzRCcM+dyWhbrVxQw9oPToTkD+ZxWb3ZuxEv++w0j+xxt\nBd/b8AoRjTPGBpyOc/ToGWN/C8AsEP4JAI/rPz8OYMjw/NdYjUMA8kR0jfxpyzM82Btq3InH71Sc\nuREnG12uVPHg7qNNy3G+rFVGPrl0ZglT5QrOT1csQxN28A1QO8qVKg6cOIvRO5eHJonBm50bx6vX\nDlQytiKsyIRXW/luxtjr+s//BODd+s8FAEYVrNf055ogovuJ6AgRHTl71loEyQlyW5/fImemyqmS\nLg0LnldvnBgyTZ0V8eZKCF72makyhvoLoYrdmTdlvWjkA2KBNiNhOY4tO8WsFvtxfcUZY48xxgYY\nYwM9PT3Of2BidP9J10p1rXJtPoeh/kJd0Ewhj3lipK2yWBEM1+Zz2FI8hidspLKDoDRVrrcyFK08\npMawjZ3XMhSa4+jVYv0zD8no/7+hP18CYLz1Xqc/5zthGwrC1bSxh++42VVqVxyIorjMjHHCqBCY\nQoafvXUZuw6dimRfjIdpRDPHaQyP7j8pDGXlcxpG71oemhyyV0O/F8B9+s/3AfiW4flf17NvVgG4\nYAjx+Eo+5DTHe1ctql+Uof4CRu9anih1xTjcmIxxVpmmzor2wmqlfHkm+u4ADM2OuUz+u50zarXh\nGyQy6ZVPAvgegF4ieo2IPgNgJ4CPENFPAPyq/hgAvgPgpwBeBPBlAL8dyFnDeRPQb3YMLWt4zEu0\nkxDEIdQahESNceOVp1oq3XkFJ84jgVf/8rRgmfx3O48/6CpcMzJZN/cwxq5hjGmMsesYY19hjL3J\nGPswY+wmxtivMsbO6ccyxtjvMMZuZIwtY4y5y5l0wYWQdVF4vM58cZKQMxInW7qleKz+81B/AbMq\n60ahE7UzYjdNvBRK2q1aw252kgSH1JKwY7yitKokmKk4qTM+cehU/fsrTpQS8f0p2gO7sfjWJW+6\nOHM6xCY2VCnu0N7JZ2RSl4KgHdqOBQkD6i3hPrt7MurTUShsIdT2DswVtbw+RLTS57n3dlo9YTqr\niTX0fEM0L9GazG+SlBo4rzN+G55npsoY3X8yVisNhcJMIZ/DIxv6cEkQUqoyJvTwnepEwhIz4yTW\n0AM1Yz+59RY8uqEvkNcXbRQmJTVw9Y0L8Mn3FWK3ySVTFalQRI0b2WXzSt9ufBOA9SsK8cq6aUdy\nWhaPbujDF+5ebqm2GPfq2JyWwaMb+nDXwCLsGVdxcEX4JL2m0EsqMF/pFydKts4VA3DghDc1AK8k\ntpUgpzhRwgNjrcV6tSxhXmcHLpQrloJF2/Yer8fa5uojmIscxZEZPSaiZAYUUbBx1SLsCrmS1W9W\nvae7/rO5taGojej8nCYtthj2ijbRht4PIw/U5E7nzenA5NZbmn535NVzDamcXEY1AyD6zHRrKlWG\n0f0nVXikBbQsYfE7uvCTNy5GfSp1tAyBKByNmVb4+uFkG3kA+OGpC/WYu9HR6+7SsO7maxqamwNX\nO1a5aXlYnCiFFr5xlCkOAy8yxYD/UsVcOpV79MWJkpIlbkN4w2gAvjgSrZAlwixjDeNSRv5W0Trd\nXRreujTTlHGjZQkb3r8Q3z76et2wZ8h9GrOdhLcssjLFifbo/c5+Me6gA7WlWlInFCEZOf5x5MxU\nGdufPe7Y5DpoRIbAScdd4Q/nBde/UmX49tHXG+QZvGSQ8Q3cWHSYijNBZb/wCxCnNMosETauWiR9\nvDLy3mFAXWM9bGTK7L3qBOW0bCzTbZPIVNmfhvZh3bATbeiDzH4p6ZsuceGelQuxY2hZooTUFO7I\noJbS9/LOdfXUPiu4TpAb+I2jUo3rzlK0RDnTrQqu/CbRhn6oP9gc8Th1P9ozXkJxooQ1S3pilxev\n8IcOF1LSbpb7r+g3DiC8jdykrRz86jHhRaTPjaSCVxJt6IHoQxRhqTCUK1Vs23tc5cXHhCAkloM2\nwmGmA+e7OkN7LxlyWtbWmE9XZqUcKLv5ntOy+MLdy/Hohj7X4yNoaZXEG/ooQxk5LYtPrVwUWlMP\nv+KCitbIEuHhO5bV4+lxh3uKYe45Rb2/lc1QrXE5roatnBoGWenOGynkc7by6OtXFDC6/yQ2jU1i\nTkfGtRMY5HeWeEPvRtysu0vDoxv6Gja8WlmylStVfPvo69jw/oX110zCxFe0xj0rF9b7Eby8c51v\nzkZQW0LcU2wleSGf06QdmkI+F7lMyNv1uhjjfodMwyAGWOpn8Yp40efq7tKwZ7xUV7icKleQJULW\nhbUP8jtLvKEf6i/gbXOds0QzBGy9bWnDBD04shZzW1yCT5UrGPv+aQwP9uLlnetaei07clrWVhO7\nkM9h46pF0kvGKMTgkgB3AB7d0IdHN/Shy+AIENWqPs1NaKyyYHJaFje9a56r9753pXxWFSB/Dbmn\n6CV5gcuBTG69BaN3Lpf6m+HBXuF3snHVooZxnM9prsatLKJ+FXz+i4x9IZ+r62dZZUCJPhdjaFpt\nV2YZOiVvjkFLqyQ6j54jk+/MYL2B5UeudGWW1fNhnXKcs3r5dJeWQXlmFoxdXQWIVoU5LVPPstj8\nzLGGAWXOtR64fkE9NVT0elkiTG69pS6lqsJBNQr5XH3TkiOz6WkukTcWN20pHsOTh09LbeybbyBO\nbLt9KYafOtpU0GOGe4pD/QVsf/a4MD/cCuPYGuovOFZcExq/M6vvxOpz8nHrV7qhk3c8PNiL4aeP\nNvR01bJXm3XzFYAZ0bXeJCisK0s0Uynkm2VX/CYVhl6mgEQ0z/wqPjF6TaJqWm5IuIHl5+RkAq7M\nNGrX8JuF1QAxDtDFI/ssX48bHfOgnZ/TUKnO4uKVmuHPaRmpgSqCV3WKtEHiRiselcgw7BhaVjds\nfkl2GN8TuHr95lpcL7OnuPW2pdI39+4urekzDQ/22v698SqLvhPRZxnqL/hS7S7tHZuHpOQQtfpc\nXm9SBDQ5F0GQ+NANIFdAIkp78qtJtdFrunfVIttmwm7FxqqMYfMzx+oDqcpY/fXsJpLd8pTDl7KP\nbOjD5ZmrRh6Q80bsmGUML+9cZ6kCGhWiWPNGQ/P3oAji9Y2hyBf+68eEIQfj8caNZB7yM38nWpaw\n9ballu/nNoffDU4bkvws8zkN3V21zdbuLq1p49Xpux7df7JpJcRX5m4oTpTqNyerOe/UgjCsvYxU\nePRGz0Z0V71n5cK64qR5KQnYa5oQgHtXLcLA9QualntATdDI6EHsGFrWEEIxv5eX3XXzjUGmfNrK\n+xJ5O0EoXRpvfvw9+MrhQtl75Wm2hRXCttuXNpyLlVppkMzrzDbcTI3Pe8UYHsoS1YvrRFh5pHbj\n1ervjUJfRlrd+7FbYfsZ4hDNQTdz0xz65Fk7vJE4n2eiFVCYkuepMPRA4+C1GvgD1y9o+MKNmjZ2\nsccsEb5w9/KGwWWMc+ZzGrbdvrRp8NktW/0OFxkx38zWryjgwImzjhPY79Qu8yA2fh/FiZJjbDlD\nwKdWLmpSCcxpWaxfUWh6XgZjKCLMpg9GPv/JZXjwqaOoGj57NkP4/Ce9eclbiscaJIGrjNUfu4n5\nuwmzANb7A1qG6jdSr4ick1bFv8yI5qAbD9vKOeJG3hyO4fbFLuwaJKkx9EaMcVHO6p3P23rFsgPM\n7YQwwo0wX+YZzZyWIbxtbkfDRhm/SR04cVZqUJo9jNJUGXvGS1KTxCq+a0c+pwklWZ0GsdWy2UiX\nlsF/u+NmDPUXhJ7mwPULhF6lCKtQRNjYbdx64cnDp4XPu93cdYPfnyPo1zXjZrUrQnZV0IrN8ItU\nGnornC5K0ANMZpknei+r7BirQWnlYciEeLYUjwmNvFl3X8sQRu+qpdl59bxE14KAphRVu+wHLiVt\nvGYXL1trgudzzRuLUeHnxBeFsMLY/A7KgIVhGP2Y736sCsKibQy9zEUJcoC5WeaZkR2UXuOOIq8w\nQ8AX7+6zfV8vE8XPCWK+ZqKbYqshBb+w2yfygmi/wovmSrvR6nz3Y1UQFm1j6KO+KK1u/sgMSq8G\nVOT9zTL79/U6UYK8FmEt/b1gFVoz7hN54Z6VCy3b9t2zcqH3E1VIEeexZqZtDH3UFyWMZZ5XAxq2\nVxj0tYhDTNQKr6E1O3gc3k3WjcI/4jrWzLSNoQeivShujLDX5b1XAxqFV5iUCeInfqT0WWGVfBA1\nfoao/A53tSNtZeijRNYIt7q892JAlVcYDknavGsFP0NUQYS72pFENwdPI6IScJlNW0W8EW0U+50j\nHjV+jmE1H+xpi+bgaSSo5b0ieqLeJwoLP8ewmg/+oAx9zGiX5X270g57E36OYTUf/CEQUTMi+igR\nnSSiF4loJIj3SCsives45uYqFFb4OYbVfPAH3z16IsoC+AsAHwHwGoAfENFextiP/X6vNNIuy3tF\nevFzDKv54A++b8YS0QcBbGOMDeqPNwMAY+xh0d+ozViFQqFwj+xmbBChmwIAY039a/pzCoVCoYiA\nyBqPENH9RHSEiI6cPXs2qtNQKBSK1BOEoS8BMJZUXqc/1wBj7DHG2ABjbKCnpyeA01AoFAoFEIyh\n/wGAm4joBiLqBPBrAPYG8D4KhUKhkMD3rBvG2AwR/S6A/QCyAL7KGDvu9/soFAqFQo5YSCAQ0VkA\nr0Z9HhHwTgA/i/okIkZ9B+o7aPfPD3j/Dq5njDnGvmNh6NsVIjoikxqVZtR3oL6Ddv/8QPDfQWRZ\nNwqFQqEIB2XoFQqFIuUoQx8tj0V9AjFAfQfqO2j3zw8E/B2oGL1CoVCkHOXRKxQKRcpRhj4kiGgu\nEX2fiI4S0XEi2m76/Z8R0VtRnV8YiL4DqvF5IvpHInqBiP5z1OcaBDaf/8NE9EMimiSivyOi90Z9\nrkFDRFkimiCib+uPbyCiw7q0+ZhebJlaLD7/E7q0+z8Q0VeJSPPz/ZShD4/LANYyxpYD6APwUSJa\nBQBENACgO8qTCwnRd/AbqMlmLGGM/SKAb0R3ioEi+vx/CeBexlgfgK8D2BLhOYbF7wN4wfD4TwA8\nwhh7L4DzAD4TyVmFh/nzPwFgCYBlAHIAftPPN1OGPiRYDe6xa/o/puv3jwL4g8hOLiRE3wGA/wTg\nIcbYrH7cGxGdYqDYfH4G4F/pz88HcCaC0wsNIroOwDoAf6U/JgBrATytH/I4gKFozi54zJ8fABhj\n39HHBwPwfdQ0wnxDGfoQ0ZdrkwDeAPBdxthhAL8LYC9j7PVozy4cBN/BjQA26Gqmf01EN0V7lsEh\n+Py/CeA7RPQagE8D2BnlOYbAo6g5NrP643cAmGKMzeiP0y5tbv78dfSQzacB/B8/31AZ+hBhjFX1\n5fl1AD5ARL8M4C4A/z3aMwsPi+/glwDMAXBJrwz8MoCvRnmOQSL4/JsA3MoYuw7A/wLwxSjPMUiI\n6OMA3mCMjUd9LlEg8fn/B4C/ZYz9Pz/fVzUHjwDG2BQRHQCwBsB7AbxYW72ii4he1OOUqcbwHXwU\nNQ/uGf1X30TN2KUaw+f/GIDlumcPAGPw2ZuLGasB3E5EtwKYi1rI6ksA8kTUoXv1ltLmKaHp8xPR\nLsbYRiLaCqAHwH/0+02VRx8SRNRDRHn95xxqPXXHGWO/wBhbzBhbDGA6zUZe8B2cAFBE7aYHAP8O\nwD9Gc4bBIvj8LwCYTySRghYAAADXSURBVET/Wj+MP5dKGGObGWPX6eP91wA8zxi7F8ABAHfqh90H\n4FsRnWKgCD7/RiL6TQCDAO7he1V+ojz68LgGwOP65msGwG7G2LcjPqewsfwOiOjvADxBRJsAvAWf\nMw5ihOjz/xaAPUQ0i1rGyX+I8iQj4nMAvkFEOwBMAPhKxOcTNv8TNQXf7+mr+2cYYw/59eKqMlah\nUChSjgrdKBQKRcpRhl6hUChSjjL0CoVCkXKUoVcoFIqUowy9QqFQpBxl6BUKhSLlKEOvUCgUKUcZ\neoVCoUg5/x9lE87Xe61HdgAAAABJRU5ErkJggg==\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6N0p91k2iFCP",
        "colab_type": "text"
      },
      "source": [
        " **尝试创建一些能够更好地利用纬度的合成特征。**\n",
        "\n",
        "例如，您可以创建某个特征，将 `latitude` 映射到值 `|latitude - 38|`，并将该特征命名为 `distance_from_san_francisco`。\n",
        "\n",
        "或者，您可以将该空间分成 10 个不同的分桶（例如 `latitude_32_to_33`、`latitude_33_to_34` 等）：如果 `latitude` 位于相应分桶范围内，则显示值 `1.0`；如果不在范围内，则显示值 `0.0`。\n",
        "\n",
        "使用相关矩阵来指导您构建合成特征；如果您发现效果还不错的合成特征，可以将其添加到您的模型中。\n",
        "\n",
        "您可以获得的最佳验证效果是什么？"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "wduJ2B28yMFl",
        "colab_type": "code",
        "cellView": "form",
        "colab": {}
      },
      "source": [
        "#\n",
        "# YOUR CODE HERE: Train on a new data set that includes synthetic features based on latitude.\n",
        "#"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "pZa8miwu6_tQ",
        "colab_type": "text"
      },
      "source": [
        " ### 解决方案\n",
        "\n",
        "点击下方即可查看解决方案。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "PzABdyjq7IZU",
        "colab_type": "text"
      },
      "source": [
        " 除了 `latitude` 之外，我们还会保留 `median_income`，以便与之前的结果进行比较。\n",
        "\n",
        "我们决定对纬度进行分桶。在 Pandas 中使用 `Series.apply` 执行此操作相当简单。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "xdVF8siZ7Lup",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "LATITUDE_RANGES = zip(range(32, 44), range(33, 45))\n",
        "\n",
        "def select_and_transform_features(source_df):\n",
        "  selected_examples = pd.DataFrame()\n",
        "  selected_examples[\"median_income\"] = source_df[\"median_income\"]\n",
        "  for r in LATITUDE_RANGES:\n",
        "    selected_examples[\"latitude_%d_to_%d\" % r] = source_df[\"latitude\"].apply(\n",
        "      lambda l: 1.0 if l >= r[0] and l < r[1] else 0.0)\n",
        "  return selected_examples\n",
        "\n",
        "selected_training_examples = select_and_transform_features(training_examples)\n",
        "selected_validation_examples = select_and_transform_features(validation_examples)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "U4iAdY6t7Pkh",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "_ = train_model(\n",
        "    learning_rate=0.01,\n",
        "    steps=500,\n",
        "    batch_size=5,\n",
        "    training_examples=selected_training_examples,\n",
        "    training_targets=training_targets,\n",
        "    validation_examples=selected_validation_examples,\n",
        "    validation_targets=validation_targets)"
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}